package com.niwodai.credit.tool.pdf;

import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.log4j.Logger;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.text.PDFTextStripperByArea;

public class App {
	public static String N = null;
	private static Logger logger = Logger.getLogger(App.class);
	public static String regJiqibianhao = "[机器编号]*(：|:)?\\s*\\d{12}\\s*";
	public static String regFapiaodaima = "[发票代码]*(：|:|\\s)?\\s*\\d{12}\\s*";
	public static String regFapiaohaoma = "[发票号码]*(：|:)?\\s*\\d{8}\\s*";
	public static String regKaipiaoriqi = "[开票日期]*(：|:)?\\s*\\d{4}[\\s*|年]+\\d{2}\\s*月*\\d{2}\\s*日*\\s*";
	public static String regJiaoyanma = "[校\\s*验\\s*码]*(：|:)?\\s*(\\d{5}\\s*){4}";
	public static String regNashuishibie = "[纳税人识别号]*(：|:)?\\s*\\w{18}\\s*";
	public static String regDaxieShuze = "((壹|贰|叁|肆|伍|陆|柒|捌|玖|拾|零|佰|仟|萬|億|万|)+(元|圆|角|分)+)+(整?)\\s*";
	public static String regXiaoxieShuze = "((¥|￥)?\\s*(\\d+).(\\d+)\\s*)+";
	public static String regBankCard = "\\D+\\d{16,20}$";
	public static String regPhoneNum = "\\D+(\\d{3,4}(-?)\\s*\\d{8}\\s*)|(\\d{11}\\s*)$";
	public static String regBuyer = "^名\\s*称：";
	
	static{
		 N = System.getProperty("line.separator");
	}
	
	public static void main(String[] args) throws Exception {
		if(args.length>=1){
			String path = args[0]; 
			String target = "";
			if(args.length >1){
				target = args[1];
			}
			long start = System.currentTimeMillis();
			getAreaText(path, target);
			long end = System.currentTimeMillis();
			logger.error(path+",costTime:" + (end -start));
		}
	}

	public static void getAreaText(String sourceFile, String targetFile) throws IOException {
		PdfInvoice pi = new PdfInvoice();
		PDDocument document = null;
		Writer writer = null;
		try {
			document = PDDocument.load(new File(sourceFile));
			PDPage page = document.getPage(0);
			PDRectangle re = page.getMediaBox();
			float width = re.getWidth();
			float height = re.getHeight();
			if(height > width ){
				height = height/2;
			}
			
			double halfWidth = width * 0.55;
			double hight1 = height * 0.25;
			double hight4 = height * 0.65;
			double hight5 = height * 0.55;
			
			String textjiqibianhao = getAreaText(page, "jiqibianhao", 0, 0, halfWidth, hight1);
			String textfapiaodaima = getAreaText(page, "fapiaodaima", width * 0.6, 0, width, hight1);
			String textgoumaifang = getAreaText(page, "goumaifang", 0, height * 0.2, halfWidth, hight1);
			String textxiaoshoufang = getAreaText(page, "xiaoshoufang", 0, hight4, halfWidth, height * 0.3);
			String textxiaoshoufang2 = getAreaText(page, "xiaoshoufang2", 0, hight5, halfWidth, height * 0.4);
			String textheji = getAreaText(page, "heji",0, height*0.55, width, height*0.3);

			getJiQiBianHaoAndBuyerName(textjiqibianhao, pi);
			getCodeAndNumAndDate(textfapiaodaima, pi);
			getBuyerInfo(textgoumaifang, pi);
			getSalerInfo(textxiaoshoufang,pi);
			if(pi.getSalerName() == ""){
				getSalerInfo(textxiaoshoufang2,pi);
			}
			getAmountInfo(textheji, pi);

			String printContent = buildPrintResult(pi);
			if (targetFile.endsWith(".txt")) {
				writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(new File(targetFile)),"utf-8"));
				writer.write(printContent);
				writer.close();
			} else {
				System.out.print(printContent);
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != document){
				document.close();
			}
			if (null != writer){
				writer.close();
			}
		}

	}
	
	public static String getAreaText(PDPage page, String areaName , double x, double y, double width, double height) throws IOException{
		PDFTextStripperByArea pts = new PDFTextStripperByArea();
		Rectangle2D area = new Rectangle();
		area.setRect(x, y, width, height);
		pts.addRegion(areaName, area);
		pts.extractRegions(page);
		String areaText = pts.getTextForRegion(areaName);
		return areaText;
	}

	public static boolean isAddressAndPhone(String text) {
		if ((text.indexOf("市") != -1 || text.indexOf("省") != -1 || text.indexOf("县") != -1 || text.indexOf("区") != -1
				|| text.indexOf("路") != -1 || text.indexOf("镇") != -1 || text.indexOf("村") != -1 || text.trim().matches(regPhoneNum))
					&& text.indexOf("超市") == -1 && text.replace(" ", "").length() >= 6 && text.indexOf("机器编号") ==-1 && !isKaihuhangAndAccount(text)) {
			return true;
		}
		return false;
	}

	public static boolean isKaihuhangAndAccount(String text) {
		if (text.indexOf("银行") != -1 || text.indexOf("支行") != -1
				|| (text.trim().matches(regBankCard) && text.length() != 18)) {
			return true;
		}
		return false;
	}
	
	public static String fixNum(String num){
		String numFix = num;
		if(num.indexOf(".") != -1){
			String [] numm = num.split("\\.");
			if(numm[1].length() == 1){
				numFix = num + "0";
			}
		}
		return numFix;
	}
	
	public static void getJiQiBianHaoAndBuyerName(String text, PdfInvoice pdfInvoice){
		String JIQIBIANHAO = "";
		String GOUMAIFANG_MINGCHENG = "";
		for (String line : text.split(N)) {
			if (line.trim().matches(regJiqibianhao)) {
				JIQIBIANHAO =  removeLabel(line.replace("机器编号:", ""));
			}
			if (line.trim().endsWith("公司") || line.indexOf("个人") != -1) {
				GOUMAIFANG_MINGCHENG =  removeLabel(line.replace("名        称：", "").replace("\r", ""));
			}
			if(GOUMAIFANG_MINGCHENG == ""){
				if(line.trim().matches(regBuyer)){
					line = removeLabel(line);
				}
			}
			if(JIQIBIANHAO != "" && GOUMAIFANG_MINGCHENG != "" ){
				break;
			}
		}
		pdfInvoice.setJiQiBianHao(JIQIBIANHAO);
		pdfInvoice.setBuyerName(GOUMAIFANG_MINGCHENG);
	}
	
	
	public static void getCodeAndNumAndDate(String text, PdfInvoice pdfInvoice){
		String FAPIAODAIMA = "";
		String FAPIAOHAOMA = "";
		String KAIPIAORIQI = "";
		String JIAOYANMA = "";
		for (String line : text.split(N)) {
			if (line.trim().matches(regFapiaodaima)) {
				FAPIAODAIMA = removeLabel(line);
				if(FAPIAODAIMA.indexOf("发票代码") != -1){
					FAPIAODAIMA = FAPIAODAIMA.replace("发票代码", "");
				}
			}
			if(FAPIAODAIMA == ""){
				if(line.indexOf("发票代码:") != -1 || line.indexOf("发票代码：") != -1){
					FAPIAODAIMA = removeLabel(line);
				}
			}
			if (line.trim().matches(regFapiaohaoma)) {
				FAPIAOHAOMA = removeLabel(line);
			}
			if (line.trim().matches(regKaipiaoriqi)) {
				KAIPIAORIQI = removeLabel(line);
				if(KAIPIAORIQI.length() == 8){
					String year = KAIPIAORIQI.substring(0,4);
					String month = KAIPIAORIQI.substring(4,6);
					String day = KAIPIAORIQI.substring(6,8);
					KAIPIAORIQI = year + "年" + month +"月" + day + "日";
				}
			}
			if(KAIPIAORIQI == ""){
				if(line.indexOf("年")!= -1 && line.indexOf("月")!= -1&&line.indexOf("日")!= -1 && line.length() > 11){
					KAIPIAORIQI = line.replace(" " , "");
				}
			}
			if (line.trim().replace("校 验 码：","").replace(" ", "").matches(regJiaoyanma)) {
				JIAOYANMA =  removeLabel(line.replace("校 验 码：", ""));
			}
			if(FAPIAODAIMA != "" && FAPIAOHAOMA != "" && KAIPIAORIQI != "" && JIAOYANMA != ""){
				break;
			}
		}
		pdfInvoice.setFaPiaoDaiMa(FAPIAODAIMA);
		pdfInvoice.setFaPiaoHaoMa(FAPIAOHAOMA);
		pdfInvoice.setKaiPiaoRiQi(KAIPIAORIQI);
		pdfInvoice.setJiaoYanMa(JIAOYANMA);
	}
	
	public static void getBuyerInfo(String text, PdfInvoice pdfInvoice){
		String GOUMAIFANG_MINGCHENG = pdfInvoice.getBuyerName();
		String GOUMAIFANG_NASHUISHIBIE = "";
		String GOUMAIFANG_DIZHI = "";
		String GOUMAIFANG_KAIHUHANG = "";
		for (String line : text.split(N)) {
			if ((line.trim().endsWith("公司") || line.indexOf("个人") != -1) && GOUMAIFANG_MINGCHENG == "") {
				GOUMAIFANG_MINGCHENG = removeLabel(line.replace("名        称：", ""));
			}
			if (line.matches(regNashuishibie) && line.indexOf("开户行及账号") == -1) {
				GOUMAIFANG_NASHUISHIBIE = removeLabel(line.replace("纳税人识别号：", ""));
			}
			if (isAddressAndPhone(line)) {
				line = line.trim();
				GOUMAIFANG_DIZHI = removeLabel(line.replace("地 址、电 话：", "").replace("开户行及账号:区", "").replace("开户行及账号: 区", ""));
			}
			if (isKaihuhangAndAccount(line)) {
				GOUMAIFANG_KAIHUHANG = removeLabel(line.replaceAll("开户行及账号：",""));
			}
			if(GOUMAIFANG_MINGCHENG !="" &&GOUMAIFANG_NASHUISHIBIE !="" &&GOUMAIFANG_DIZHI !="" &&GOUMAIFANG_KAIHUHANG !=""  ){
				break;
			}
		}
		pdfInvoice.setBuyerName(GOUMAIFANG_MINGCHENG);
		pdfInvoice.setBuyerNaShuiShiBie(GOUMAIFANG_NASHUISHIBIE);
		pdfInvoice.setBuyerAddress(GOUMAIFANG_DIZHI);
		pdfInvoice.setBuyerKaiHuHang(GOUMAIFANG_KAIHUHANG);
	}
	
	public static void getSalerInfo(String text, PdfInvoice pdfInvoice){
		String XIAOSHOUFANG_MINGCHENG = "";
		String XIAOSHOUFANG_NASHUISHIBIE = "";
		String XIAOSHOUFANG_DIZHI = "";
		String XIAOSHOUFANG_KAIHUHANG = "";
		for (String line : text.split(N)) {
			if (line.trim().endsWith("公司") || line.indexOf("个人") != -1) {
				XIAOSHOUFANG_MINGCHENG = removeLabel(line.replaceAll("名        称：", "").replace("\r", ""));
			}
			if (line.matches(regNashuishibie)&& line.indexOf("开户行及账号") == -1) {
				XIAOSHOUFANG_NASHUISHIBIE = removeLabel(line.replace("纳税人识别号：", ""));
			}
			if (isAddressAndPhone(line) && !line.trim().endsWith("公司")) {
				XIAOSHOUFANG_DIZHI = removeLabel(line.replaceAll("地\\s*址、电\\s*话：\\s*", "").replace("地 址、电 话：", ""));
			}
			if (isKaihuhangAndAccount(line)) {
				XIAOSHOUFANG_KAIHUHANG = removeLabel(line.replaceAll("开户行及账号：",""));
			}
		}
		pdfInvoice.setSalerName(XIAOSHOUFANG_MINGCHENG);
		pdfInvoice.setSalerNaShuiShiBie(XIAOSHOUFANG_NASHUISHIBIE);
		pdfInvoice.setSalerAddress(XIAOSHOUFANG_DIZHI);
		pdfInvoice.setSalerKaiHuHang(XIAOSHOUFANG_KAIHUHANG);
	}
	
	public static void getAmountInfo(String text, PdfInvoice pdfInvoice){
		text = text.replaceAll("合 *\\s*计", "").replace("价税（大写）", "").replace("（小写）", "").replace("价税(大写)", "").replace("(小写)", "").replace("⊙", "").replace(" �", "");
		String HEJI_DAXIE = "";
		List<Double> xiaoXieNums = new ArrayList<Double>();
		for (String line : text.split(N)) {
			line = line.trim();
			String lineDaxie = line.replaceAll(regXiaoxieShuze, "");
			String lineXiaoXie = line.replaceAll(regDaxieShuze, "");
			if (lineDaxie.matches(regDaxieShuze)) {
				HEJI_DAXIE = lineDaxie.replace(" ", "");
			}

			if (lineXiaoXie.matches(regXiaoxieShuze) && lineXiaoXie.indexOf(".")!= -1) {
				lineXiaoXie = lineXiaoXie.trim().replace(" ", "");
				// ¥|￥
				if (lineXiaoXie.indexOf("¥") != -1) {
					String[] ss = lineXiaoXie.split("¥");
					for (String s : ss) {
						s = s.replace(" ", "");
						if (s.length() > 0) {
							xiaoXieNums.add(Double.valueOf(s));
						}
					}
				} else if (lineXiaoXie.indexOf("￥") != -1) {
					String[] ss = lineXiaoXie.split("￥");
					for (String s : ss) {
						s = s.replace(" ", "").trim();
						if (s.length() > 0) {
							xiaoXieNums.add(Double.valueOf(s));
						}
					}
				} else {
					if(xiaoXieNums.size() < 3 ){
						lineXiaoXie = lineXiaoXie.replace(" ", "");
						if (lineXiaoXie.length() > 0) {
							xiaoXieNums.add(Double.valueOf(lineXiaoXie));
						}
					}
				}
			}
		}
		
		if(xiaoXieNums.size() <3){
			for(int i = 0; i<= 4-xiaoXieNums.size();i++ ){
				xiaoXieNums.add(Double.MAX_VALUE);
			}
		}
		Collections.sort(xiaoXieNums);
		double amount1 = xiaoXieNums.get(0);
		double taxAmount = xiaoXieNums.get(1);
		double totalAmount = xiaoXieNums.get(2);
		if(amount1 == taxAmount && amount1 != Double.MAX_VALUE && totalAmount ==Double.MAX_VALUE){
			xiaoXieNums.set(0, 0.0);
			xiaoXieNums.set(2, amount1);
		}
		
		if(amount1 != Double.MAX_VALUE && taxAmount== totalAmount && totalAmount ==Double.MAX_VALUE){
			xiaoXieNums.set(0, 0.0);
			xiaoXieNums.set(1, amount1);
			xiaoXieNums.set(2, amount1);
		}
		
		if(amount1 != Double.MAX_VALUE && taxAmount != Double.MAX_VALUE && totalAmount != Double.MAX_VALUE){
			if( new BigDecimal(amount1).add(new BigDecimal(taxAmount)).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue() 
					!= new BigDecimal(totalAmount).setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue()){
				xiaoXieNums.set(0, (new BigDecimal(totalAmount).remainder(new BigDecimal(taxAmount)))
						.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue()); 
			}
		}
		
		pdfInvoice.setTotalDaXie(HEJI_DAXIE);
		pdfInvoice.setXiaoXieNums(xiaoXieNums);
	}
	
	public static String buildPrintResult(PdfInvoice pi){
		List<String> numsToPrint = new ArrayList<String>();
		numsToPrint.add(0, fixNum(pi.getXiaoXieNums().get(1).toString()));
		numsToPrint.add(1, fixNum(pi.getXiaoXieNums().get(0).toString()));
		numsToPrint.add(2, pi.getTotalDaXie());
		numsToPrint.add(3, fixNum(pi.getXiaoXieNums().get(2).toString()));
		
		StringBuilder sb = new StringBuilder("");
		sb.append(pi.getFaPiaoDaiMa() + N);
		sb.append(pi.getFaPiaoHaoMa() + N);
		sb.append(pi.getKaiPiaoRiQi() + N);
		sb.append(pi.getJiaoYanMa() + N);
		sb.append(pi.getBuyerName() + N);
		sb.append(pi.getBuyerNaShuiShiBie() + N);
		sb.append(pi.getBuyerAddress() + N);
		sb.append(pi.getBuyerKaiHuHang() + N);
		for(int i = 0; i< numsToPrint.size(); i++){
			if(numsToPrint.get(i).equals(Double.MAX_VALUE+"")){
				sb.append( N);
			}else{
				sb.append(numsToPrint.get(i) +N);
			}
		}
		sb.append(pi.getSalerName() + N);
		sb.append(pi.getSalerNaShuiShiBie() +N);
		sb.append(pi.getSalerAddress() + N);
		sb.append(pi.getSalerKaiHuHang() +N);
		sb.append(pi.getJiQiBianHao() + N);
		return sb.toString();
	}
	
	public static String removeLabel(String text){
		if(text.indexOf("：") != -1){
			String [] ss = text.split("：");
			if(ss.length>1){
				text = text.split("：")[1].trim();
			}
		}else if(text.indexOf(":") != -1){
			String [] ss = text.split(":");
			if(ss.length>1){
				text = text.split(":")[1].trim();
			}
		}
		text = text.replace(" ", "");
		text = text.replace("　", "");
		return text;
	}
}
